﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows.Forms;

namespace GestionBudget.Objects
{
    public class SousCategorie : Categorie
    {
        private const string NOM_FICHIER_XML = "souscategories.xml";

        private bool estCompressible;
        private bool estRevenu;
        private Categorie categorieParent;
        private Profil profil;

        public static SousCategorie Creer(Profil profilCourant)
        {
            SousCategorie nouvelleSousCategorie = new SousCategorie()
            {
                profil = profilCourant
            };

            DictionnaireDonnees.ListeSousCategories.Add(nouvelleSousCategorie);
            return nouvelleSousCategorie;
        }

        private SousCategorie()
        {

        }

        private SousCategorie(string identifiantSouscategorie, string descriptionSousCategorie, bool estCompressible, bool estRevenu, string profil, string CategorieParent) 
            : base(identifiantSouscategorie, descriptionSousCategorie)
        {
            
            this.identifiant = Convert.ToInt32(identifiantSouscategorie);
            this.description = descriptionSousCategorie;
            this.estCompressible = estCompressible;
            this.estRevenu = estRevenu;
            if (Convert.ToInt32(profil) > 0)
            {
                this.profil = DictionnaireDonnees.ListeProfils.First(pr => pr.ToString().Equals(profil));
            }
            if (Convert.ToInt32(CategorieParent) > 0)
            {
                this.categorieParent = DictionnaireDonnees.ListeCategories.First(c => c.Identifiant.ToString().Equals(CategorieParent));
            }

        }

        public bool EstCompressible
        {
            get { return estCompressible; }
            set
            {
                estCompressible = (estRevenu ? false : value);
                if (estCompressible != value)
                {
                    SetEstModifieTrue();
                }
            }
        }

        public bool EstRevenu
        {
            get { return estRevenu; }
            set
            {
                estCompressible = !value;
                if (estRevenu != value)
                {
                    SetEstModifieTrue();
                }
                estRevenu = value;
            }
        }

        public Categorie CategorieParent
        {
            get
            {
                return categorieParent;
            }
            set
            {
                if (categorieParent != value)
                {
                    SetEstModifieTrue();
                }
                categorieParent = value;
            }
        }

        public Profil Profil
        {
            get { return profil; }
            set { profil = value; }
        }

        public SousCategorie Self
        {
            get { return this; }
        }

        public string Type
        {
            get
            {
                return (this.EstRevenu ? "Revenu" : "Dépense");
            }
        }

        static public List<SousCategorie> ChargerListe()
        {
            CreerFichier(NOM_FICHIER_XML, "SousCategories");

            try
            {
                List<SousCategorie> ListeSousCategorie = new List<SousCategorie>();
                XElement xelement = XElement.Load(NOM_FICHIER_XML);

                IEnumerable<XElement> sousCategorie = xelement.Elements();

                foreach (var sc in sousCategorie)
                {
                    SousCategorie nouvelleSouscategorie = new SousCategorie(sc.Element("identifiant").Value,
                                                                            sc.Element("description").Value,
                                                                            Convert.ToBoolean(sc.Element("estCompressible").Value),
                                                                            Convert.ToBoolean(sc.Element("estRevenu").Value),
                                                                            sc.Element("profil").Value,
                                                                            sc.Element("categorieParent").Value);
                    ListeSousCategorie.Add(nouvelleSouscategorie);
                }

                return ListeSousCategorie;
            }
            catch (Exception e)
            {
                MessageBox.Show("Une erreur est survenue lors du chargement des sous-catégorie; " + e.Message, "Attention", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return null;
            }
        }

        public override void Sauvegarder()
        {
            CreerFichier(NOM_FICHIER_XML, "SousCategories");

            try
            {
                if (this.EstModifie || this.EstNouveau)
                {
                    XDocument xDocument = XDocument.Load(NOM_FICHIER_XML);

                    if (this.EstNouveau)
                    {
                        if (this.Identifiant == 0)
                        {
                            AttribuerIdentifiant();
                        }

                        xDocument.Root.Add(new XElement("SousCategorie", new XElement("identifiant", this.identifiant.ToString()),
                                                                        new XElement("description", this.description),
                                                                        new XElement("estCompressible", this.EstCompressible.ToString()),
                                                                        new XElement("estRevenu", this.EstRevenu.ToString()),
                                                                        new XElement("profil", this.profil.ToString()),
                                                                        new XElement("categorieParent", this.CategorieParent.Identifiant.ToString())));
                    }
                    else if (this.EstModifie)
                    {
                        IEnumerable<XElement> souscategories = xDocument.Elements();
                        XElement elementsouscategorie = (from souscategorie in souscategories.Elements()
                                                         where souscategorie.Element("identifiant").Value.Equals(this.Identifiant.ToString())
                                                         select souscategorie).First();
                        elementsouscategorie.Element("identifiant").Value = this.Identifiant.ToString();
                        elementsouscategorie.Element("description").Value = this.Description;
                        elementsouscategorie.Element("estCompressible").Value = this.EstCompressible.ToString();
                        elementsouscategorie.Element("estRevenu").Value = this.EstRevenu.ToString();
                        elementsouscategorie.Element("profil").Value = this.profil.ToString();
                        elementsouscategorie.Element("categorieParent").Value = this.CategorieParent.Identifiant.ToString();
                    }

                    xDocument.Save(NOM_FICHIER_XML);

                    base.Sauvegarder();
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Une erreur est survenue lors de la sauvegarde d'une sous-catégorie; " + e.Message, "Attention", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        public override void Supprimer()
        {
            bool peutSupprimer = true;
            List<Transaction> ListeTransactionsLiees = DictionnaireDonnees.ListeTransactions.Where(t => t.SousCategorie == this).ToList();
            
            if (ListeTransactionsLiees.Count > 0)
            {
                peutSupprimer = (MessageBox.Show(String.Format("Plusieurs transactions sont liées à la sous-catégorie {0}. " +
                                                    "Si vous supprimer la sous-catégorie, les transactions liées seront perdu. " +
                                                    "Voulez-vous continuer?", this.description),
                                                    "Attention",
                                                    MessageBoxButtons.YesNo) == DialogResult.Yes);
            }

            if (peutSupprimer)
                {
                    if (!this.EstNouveau)
                    {
                        try
                        {
                            XDocument xDocument = XDocument.Load(NOM_FICHIER_XML);
                            IEnumerable<XElement> souscategories = xDocument.Elements();
                            XElement elementsouscategorie = (from souscategorie in souscategories.Elements()
                                                             where souscategorie.Element("identifiant").Value.Equals(this.Identifiant.ToString())
                                                             select souscategorie).First();
                            elementsouscategorie.Remove();
                            xDocument.Save(NOM_FICHIER_XML);
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Une erreur est survenue lors de la suppression d'une sous-catégorie; " + e.Message, "Attention", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        }
                    }

                    foreach (Transaction trans in ListeTransactionsLiees)
                    {
                        trans.Supprimer();
                    }

                    DictionnaireDonnees.ListeSousCategories.Remove(this);
                    this.Dispose();
                }
        }

        public override void AttribuerIdentifiant()
        {
            if (this.identifiant == 0)
            {
                this.identifiant = DictionnaireDonnees.ListeSousCategories.OrderBy(sc => sc.Identifiant).Last().Identifiant + 1;
            }
        }

        public override string ToString()
        {
            return base.ToString();
        }
    }
}
